package highscore;

import java.io.PrintStream;

/**
 * Used to display the highscore in various ways.
 *
 * @author Swedman Skomakar'n
 */
public class HighscorePrinter
{
    /**
     * Variable to save the Highscore associated with this HighscoreFileHandler in
     */
    private Highscore highscore;

    /**
     * Creates a new Highscore to associate with this HighscorePrinter
     * You can use getHighscore() to get the associated highscore
     *
     * @see HighscorePrinter#getHighscore()
     */
    public HighscorePrinter()
    {
		this(null);
    }

    /**
     * HighscorePrinter constructor.
     *
     * @param highscore The highscore object to print.
     */
    public HighscorePrinter(Highscore highscore)
    {
		if (highscore == null)
			this.highscore = new Highscore();
		else
			this.highscore = highscore;
    }

    /**
     * Used to get the value of the highscore varialbe
     * @return The Highscore linked with the HighscorePrinter
     */
    public Highscore getHighscore()
    {
		return highscore;
    }

    /**
     * Prints the highscores to the console using System.out
     */
    public void printAll()
    {
		printAll(System.out);
    }

    /**
     * Prints the highscore to the specified PrintStream
     * @param out The PrintStream to write to
     */
    public void printAll(PrintStream out)
    {
		out.print(getFormatedString());
    }

    /**
     * Formats the highscore so it can be printed easilly
     * @return A String containing the highscore information
     */
    private String getFormatedString()
    {
		String sep = "\n\n-----------------------------\n\n";
		// The reason that I do this is because we do not want a reference, we want a copy
		String ret = new String(sep);

		int max = highscore.getRowCount();

		for (int i = 0; i < max; i++)
		{
			ret += highscore.getRowAt(i) + sep;
		}

		return ret;
    }

    /**
     * Prints a formatted highscore list, considering entrants with the same score to share place.
     * You have to order the list yourself first.
     */

    public void printInOrderShared()
    {
        int place = 1, previous = 0;
        int nameLength = 0, scoreLength = Integer.toString(highscore.getRowCount()).length() + 1;

        // Find the longest name.
        for (int i = 0; i < highscore.getRowCount(); i ++)
            if (highscore.getRowAt(i).getName().length() > nameLength)
                nameLength = highscore.getRowAt(i).getName().length() + 1;

        for (int i = 0; i < highscore.getRowCount(); i ++)
        {
            String score = "";

            if (place > previous)
                score = Integer.toString(place) + ":";

            while (score.length() < scoreLength)
                score = " " + score;

            score += " ";
            previous = place;
            String name = highscore.getRowAt(i).getName() + " ";

            while (name.length() < nameLength)
                name += "~";

            System.out.println(score + name + "~ " + highscore.getRowAt(i).getScore());

            if (i < highscore.getRowCount() - 1 && highscore.getRowAt(i).getScore() != highscore.getRowAt(i + 1).getScore())
                place ++;
        }
    }

    /**
     * Prints a formatted highscore list, not considering entrants with the same score to share place.
     * You have to order the list yourself first.
     */

    public void printInOrderSeparated()
    {
        int nameLength = 0, scoreLength = Integer.toString(highscore.getRowCount()).length() + 1;

        // Find the longest name.
        for (int i = 0; i < highscore.getRowCount(); i ++)
            if (highscore.getRowAt(i).getName().length() > nameLength)
                nameLength = highscore.getRowAt(i).getName().length() + 1;

        for (int i = 0; i < highscore.getRowCount(); i ++)
        {
            String score = Integer.toString(i + 1) + ":";

            while (score.length() < scoreLength)
                score = " " + score;

            score += " ";
            String name = highscore.getRowAt(i).getName() + " ";

            while (name.length() < nameLength)
                name += "~";

            System.out.println(score + name + "~ " + highscore.getRowAt(i).getScore());
        }
    }
}
